package com.libs.utils;

import com.baidu.aip.ocr.AipOcr;
import com.libs.sys.model.Userseat;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.impl.client.CloseableHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Random;

/**
 * @author xucc on  2021/10/15 8:52
 */
@Component
@Slf4j
public class BaiduOCR {
    //设置APPID/AK/SK
    public static final String APP_ID = "25001638";
    public static final String API_KEY = "hrw3owO4fiRH5EqWyAdBmLG1";
    public static final String SECRET_KEY = "GvZkQ9t0CrsDgw4ifoz47F9IlKBiPcKA";

    public static void main(String[] args) throws Exception {
//        String loginCode = getLoginCode(HttpClientConn.getHttpClientTest());
//        String s = "A23";
//        System.out.println(loginCode.length() + "===s" + s.length());
//        if (loginCode.length() == 4) {
//            System.out.println(true);
//        }
//        Userseat userseat = new Userseat("18037110", "070010", "100455730");
//        getCode(userseat,HttpClientConn.getHttpClient(), false);
        test();
    }

    public static void test() throws Exception {
        // 初始化一个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        CloseableHttpResponse getImgRes = HttpClientConn.getGetRes("https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?",
                false, HttpClientConn.getHttpClient());
        InputStream content = getImgRes.getEntity().getContent();
        BufferedImage img = ImageIO.read(content);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(img, "JPEG", outputStream);
        FileOutputStream fileOutputStream = new FileOutputStream("G:\\project\\libs\\src\\main\\resources\\img\\1.jpeg");
        fileOutputStream.write(outputStream.toByteArray());
        outputStream = new ByteArrayOutputStream();
        ImageIO.write(cleanColor(img.getSubimage(6, 4, 48, 15)), "JPEG", outputStream);
        fileOutputStream = new FileOutputStream("G:\\project\\libs\\src\\main\\resources\\img\\2.jpeg");
        fileOutputStream.write(outputStream.toByteArray());
        JSONObject res = client.basicGeneral(outputStream.toByteArray(), new HashMap<>());
        System.out.println(res);
        System.out.println(res.getJSONArray("words_result").getJSONObject(0).getString("words").substring(1));
    }

    public static String getCode(Userseat userseat, CloseableHttpClient httpClient, boolean islogin) throws Exception {
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        String url = "https://lib-seat.chu.edu.cn/ClientWeb/pro/page/image.aspx?";
//        String msn = "登录";
        if (!islogin) {
            url += new Random().nextDouble();
//            msn = "抢座";
        }
        String words = "";
        do {
            CloseableHttpResponse getImgRes = HttpClientConn.getGetRes(url, false, httpClient);
            InputStream content = getImgRes.getEntity().getContent();
            BufferedImage img = ImageIO.read(content);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(img, "JPEG", outputStream);
            ImageIO.write(cleanColor(img.getSubimage(6, 4, 48, 15)), "JPEG", outputStream);
//            JSONObject res = client.basicGeneral(outputStream.toByteArray(), new HashMap<>());
            JSONObject res = client.basicAccurateGeneral(outputStream.toByteArray(), new HashMap<>());
            JSONArray words_result = res.getJSONArray("words_result");
            if (words_result != null) {
                JSONObject jsonObject = words_result.getJSONObject(0);
                words = jsonObject.getString("words").replaceAll("[^a-zA-Z0-9]", "");
//                log.info("{}:{}验证码=[{}]",userseat.getUid() ,msn,words);
                if (words.length() == 4) {
                    return words;
                }
            }
        } while (true);
    }

    public static BufferedImage cleanColor(BufferedImage image) {
        //获取图片的高宽
        int width = image.getWidth();
        int height = image.getHeight();
        //循环执行除去干扰像素
        for (int i = 1; i < width; i++) {
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    Color color = new Color(image.getRGB(x, y));
                    if (color.getRed() > 130 && color.getGreen() > 130 && color.getBlue() > 140) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    } else if (color.getRed() == color.getGreen() || color.getBlue() == color.getGreen() || color.getRed() == color.getGreen()) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    } else if (color.getBlue() < 40) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        //循环执行除去干扰像素
        for (int i = 1; i < width; i++) {
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    Color color = new Color(image.getRGB(x, y));
                    if (color.getRed() == color.getGreen() || color.getBlue() == color.getGreen() || color.getRed() == color.getGreen()) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        return denoise(image);
    }


    /**
     * 降噪，以1个像素点为单位（实际使用中可以循环降噪，或者把单位可以扩大为多个像素点）
     */
    public static BufferedImage denoise(BufferedImage image) {
        int width = image.getWidth();
        int height = image.getHeight();
        int white = new Color(255, 255, 255).getRGB();

        if (isWhite(new Color(image.getRGB(1, 0))) && isWhite(new Color(image.getRGB(0, 1)))
                && isWhite(new Color(image.getRGB(1, 1)))) {
            image.setRGB(0, 0, white);
        }
        if (isWhite(new Color(image.getRGB(width - 2, 0))) && isWhite(new Color(image.getRGB(width - 1, 1)))
                && isWhite(new Color(image.getRGB(width - 2, 1)))) {
            image.setRGB(width - 1, 0, white);
        }
        if (isWhite(new Color(image.getRGB(0, height - 2))) && isWhite(new Color(image.getRGB(1, height - 1)))
                && isWhite(new Color(image.getRGB(1, height - 2)))) {
            image.setRGB(0, height - 1, white);
        }
        if (isWhite(new Color(image.getRGB(width - 2, height - 1))) && isWhite(new Color(image.getRGB(width - 1, height - 2)))
                && isWhite(new Color(image.getRGB(width - 2, height - 2)))) {
            image.setRGB(width - 1, height - 1, white);
        }
        int size = 0;
        for (int x = 1; x < width - 1; x++) {
            int y = 0;
            if (isBlack(new Color(image.getRGB(x, y)))) {

                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }
        for (int x = 1; x < width - 1; x++) {
            int y = height - 1;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }

        for (int y = 1; y < height - 1; y++) {
            int x = 0;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                    size++;
                }
                if (size >= 4) {
                    image.setRGB(x, y, white);
                }
            }
        }

        for (int y = 1; y < height - 1; y++) {
            int x = width - 1;
            if (isBlack(new Color(image.getRGB(x, y)))) {
                size = 0;
                if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                    size++;
                }
                //斜上下为空时，去掉此点
                if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                    size++;
                }
                if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                    size++;
                }
                if (size >= 5) {
                    image.setRGB(x, y, white);
                }
            }
        }

        //降噪，以1个像素点为单位
        for (int y = 1; y < height - 1; y++) {
            for (int x = 1; x < width - 1; x++) {
                if (isBlack(new Color(image.getRGB(x, y)))) {
                    size = 0;
                    //上下左右均为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x - 1, y)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y)))) {
                        size++;
                    }
                    //上下均为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x, y - 1)))) {
                        size++;
                    }
                    //斜上下为空时，去掉此点
                    if (isWhite(new Color(image.getRGB(x - 1, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y - 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x + 1, y + 1)))) {
                        size++;
                    }
                    if (isWhite(new Color(image.getRGB(x - 1, y - 1)))) {
                        size++;
                    }
                    if (size >= 7) {
                        image.setRGB(x, y, Color.WHITE.getRGB());
                    }
                }
            }
        }
        return image;
    }

    public static boolean isBlack(Color color) {
        return color.getRed() + color.getGreen() + color.getBlue() <= 580 || color.getBlue() > 205 || color.getRed() > 190;
    }

    public static boolean isWhite(Color color) {
        return color.getRed() + color.getGreen() + color.getBlue() > 680;
    }
}
